﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Chromium;
using Chromium.Event;
using Chromium.Remote.Event;
using Chromium.WebBrowser;
using Fasterflect;
using Kugar.Core.ExtMethod;
using NetDimension.NanUI;

namespace Kugar.UI.RazorUI
{
    public partial class RazorUIForm : Formium
    {
        //private CefRazorFormBase _currentRazorForm = null;
        private static string _innerScriptFile = "";
        private Dictionary<long, CefRazorFormBase> _frameMappers=new Dictionary<long, CefRazorFormBase>();
        private bool _isFirstTime = true;
        private string _url = "";

        static RazorUIForm()
        {
            string resourceName = typeof(RazorUIForm).Assembly.GetManifestResourceNames()
                .Single(str => str.EndsWith("razorui.js"));

            using (Stream stream = typeof(RazorUIForm).Assembly.GetManifestResourceStream(resourceName))
            using (StreamReader reader = new StreamReader(stream))
            {
                _innerScriptFile = reader.ReadToEnd();
            }
        }


        public RazorUIForm(string url):base(url.StartsWith("http",StringComparison.CurrentCultureIgnoreCase)?url: ("http://assets.razor.local" + url))
        {
            InitializeComponent();

            JSObject go = GlobalObject;

            if (go != null)
            {
                if (go.ContainsKey("cSharpRazorUI"))
                {
                    go.Remove("cSharpRazorUI");
                }
                var c = go.AddObject("cSharpRazorUI");

                //var currentEmbedObject = go.AddObject("cSharpRazorUI");
                c.AddFunction("proxyCall").Execute += JsProxyCall_Execute;
            }

            LoadHandler.OnLoadStart += LoadHandler_OnLoadStart;
            LoadHandler.OnLoadEnd += LoadHandler_OnLoadEnd;
            LoadHandler.OnLoadingStateChange += LoadHandler_OnLoadingStateChange;
            
            RequestHandler.OnBeforeBrowse += RequestHandler_OnBeforeBrowse;
            RequestHandler.OnOpenUrlfromTab += RequestHandler_OnOpenUrlfromTab;            



            //_url = "http://assets.razor.local" + url;
        }

        internal void SetCurrentHandleForm(CfxFrame frame, CefRazorFormBase frm)
        {
            if (_frameMappers.TryGetValue(frame.Identifier, out var tmp))
            {
                if (tmp != frm)
                {
                    tmp.OnFormClosed();
                }
            }
            _frameMappers.AddOrUpdate(frame.Identifier, frm);
            //_currentRazorForm = frm;
        }
        
        internal CfrV8HandlerExecuteEventHandler MainFrameProxyCallExecute { set; get; }

        

        private void LoadHandler_OnLoadingStateChange(object sender, Chromium.Event.CfxOnLoadingStateChangeEventArgs e)
        {
            if (e.IsLoading==false)
            {
                //LoadUrl(_url);
                //Chromium.ShowDevTools();
                //onFrameLoaded(e.Browser.MainFrame);
            }
        }

        private void RequestHandler_OnOpenUrlfromTab(object sender, Chromium.Event.CfxOnOpenUrlfromTabEventArgs e)
        {
            
            if(e.TargetDisposition== CfxWindowOpenDisposition.NewPopup || e.TargetDisposition== CfxWindowOpenDisposition.NewWindow)
            {
                e.SetReturnValue(false);
                (new RazorUIForm(e.TargetUrl)).Show();
            }
        }

        private void RequestHandler_OnBeforeBrowse(object sender, Chromium.Event.CfxOnBeforeBrowseEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(e.Frame.Url) || !e.Frame.Url.StartsWith("http",StringComparison.CurrentCultureIgnoreCase))
            {
                return;
            }
            
            if (e.Frame.IsMain)
            {
                if (_frameMappers.TryGetValue(e.Frame.Identifier, out var frm))
                {
                    frm?.OnFormClosed();

                    if (!string.IsNullOrWhiteSpace(e.Frame.Url))
                    {
                        _frameMappers.Clear();
                    }
                    
                }
            }
            //go = this.GlobalObjectForFrame(e.Frame.Name);

            //go?.Remove("CSharpRazorUI");
            
            
        }

        private void LoadHandler_OnLoadEnd(object sender, Chromium.Event.CfxOnLoadEndEventArgs e)
        {
            onFrameLoaded(e.Frame);
        }

        private void LoadHandler_OnLoadStart(object sender, Chromium.Event.CfxOnLoadStartEventArgs e)
        {
            if (!e.Frame.IsMain)
            {
                return;
            }

            var frame = e.Frame;

            if (string.IsNullOrWhiteSpace(frame.Url) ||
                !frame.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            frame.ExecuteJavaScript(_innerScriptFile, "", 0);
        }



        private void onFrameLoaded(CfxFrame frame)
        {
            if (string.IsNullOrWhiteSpace(frame.Url) || !frame.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }
            

            if (frame.IsMain)
            {
                Chromium.ShowDevTools();
            }

            if (_frameMappers.TryGetValue(frame.Identifier,out var tmp))
            {
                tmp.OnFormLoaded();
            }

        }

        private void JsProxyCall_Execute(object sender, CfrV8HandlerExecuteEventArgs e)
        {
            MainFrameProxyCallExecute?.Invoke(sender,e);
        }

    }
}
